//
// Created by 74354 on 2022/1/21.
//
#include "canConfig.h"
#include "main.h"
CAN_TxHeaderTypeDef TxMeg;      // 发送的结构体
CAN_RxHeaderTypeDef RxMeg;      // 接收的结构体


void CAN::sendDataFrame(FrameSizeType type,uint32_t ID, uint8_t *pData, uint16_t Len) {
    if (!pData || !Len) return;
    if(type == Expanded)
    {
        TxMeg.StdId = (ID & 0X1FFC0000) >> 18;
        TxMeg.ExtId = (ID & 0X3FFFF);
        TxMeg.IDE = CAN_ID_EXT;
    }
    else if(type == Standard)
    {
        TxMeg.StdId = ID & 0X7FF;
        TxMeg.IDE = CAN_ID_STD;
    }
    TxMeg.RTR = CAN_RTR_DATA;
    TxMeg.DLC = Len;
    while(!HAL_CAN_GetTxMailboxesFreeLevel(&handleCAN)){}
    HAL_CAN_AddTxMessage(&handleCAN,&(TxMeg),pData,(uint32_t *) CAN_TX_MAILBOX0);
}



void CAN_User_Init(CAN_HandleTypeDef* hcan) //用户初始化函数
{
    CAN_FilterTypeDef sFilterConfig;

    sFilterConfig.FilterBank = 0;                           // 过滤器0
    sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;       // 设为列表模式
    sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;      // 过滤尺度是16位

    sFilterConfig.FilterIdHigh = ((NODE1_ID << 3) & 0XFFFF0000)>>16;           // 基本ID放入到STID中，可用于循环模式时的信息过滤
    sFilterConfig.FilterIdLow = (NODE1_ID << 3) & 0X0000FFF8;

    sFilterConfig.FilterMaskIdHigh = 0X000;            //
    sFilterConfig.FilterMaskIdLow = 0X000<<3;

    sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;      // 接收到的报文放入到FIFO0中
    sFilterConfig.FilterActivation = ENABLE;                // 激活过滤器
    sFilterConfig.SlaveStartFilterBank = 0;

    if(HAL_CAN_ConfigFilter(hcan, &sFilterConfig)!=HAL_OK){
        Error_Handler();
    }
    if(HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING)!=HAL_OK){
        Error_Handler();
    }

    HAL_CAN_Start(&hcan1); //开启CAN
}

extern CAN can;

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) //接收回调函数
{
    uint8_t Data[8];
    uint32_t id;
    HAL_StatusTypeDef HAL_RetVal;
    if (hcan == &hcan1) {
        HAL_RetVal = HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &RxMeg, Data);
        if (HAL_OK == HAL_RetVal)
        {
            // 在这里接收数据
//            CANx_SendNormalData(&hcan1,1234,Data,8);
            id = (RxMeg.StdId << 18)|(RxMeg.ExtId);
            // can.sendDataFrame(Expanded,id1,Data,8);
            CanReceiveCallback(id,Data,RxMeg.DLC);
        }
    }
}

//发送数据函数
uint8_t CANx_SendNormalData(CAN_HandleTypeDef *hcan, uint16_t ID, uint8_t *pData, uint16_t Len) {
    HAL_StatusTypeDef HAL_RetVal;
    uint16_t SendTimes, SendCNT = 0;
    uint8_t FreeTxNum = 0;
    TxMeg.StdId = ID;
    if (!hcan || !pData || !Len) return 1;
    SendTimes = Len / 8 + (Len % 8 ? 1 : 0);
    FreeTxNum = HAL_CAN_GetTxMailboxesFreeLevel(&hcan1);
    TxMeg.DLC = 8;
    while (SendTimes--) {

        if (0 == SendTimes) {

            if (Len % 8)
                TxMeg.DLC = Len % 8;
        }
        while (0 == FreeTxNum) {

            FreeTxNum = HAL_CAN_GetTxMailboxesFreeLevel(&hcan1);
        }
        HAL_Delay(1); //没有延时很有可能会发送失败
        HAL_RetVal = HAL_CAN_AddTxMessage(&hcan1, &TxMeg, pData + SendCNT, (uint32_t *) CAN_TX_MAILBOX0);
        if (HAL_RetVal != HAL_OK) {

            return 2;
        }
        SendCNT += 8;
    }

    return 0;
}
